home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxutil / tspak17 / time_div.asm < prev    next >
Assembly Source File  |  1994-08-31  |  5KB  |  227 lines

  1. ; TIME_DIV.ASM
  2. ;
  3. ; External assembler subroutine for Recwav.pas.  This routine measures the
  4. ; number of bytes transferred in 8 timer ticks (524,288 PIT clock counts, or
  5. ; 0.4394 seconds) by the DAC when recording sound using the given input
  6. ; divider.  The number of bytes is returned.  Sound samples are placed in
  7. ; the 65535-byte buffer whose pointer is passed to the subroutine.
  8. ;
  9. ; A Tandy DAC is assumed to be present; time_div() gets its address from
  10. ; the BIOS.  This subroutine takes over the timer tick and bypasses the
  11. ; BIOS, programming the PIT, the DMA controller, and the sound chip directly.
  12. ;
  13. ; The Turbo Pascal invocation syntax is:
  14. ;
  15. ; function time_div(
  16. ;   buffer:                    (* buffer to fill *)
  17. ;     pointer;
  18. ;   divider:                   (* divider to use *)
  19. ;     word ):
  20. ;       word;
  21. ;
  22.  
  23. CODE        SEGMENT    BYTE PUBLIC
  24.         ASSUME    CS:CODE,DS:CODE
  25.         PUBLIC    TIME_DIV
  26. TIME_DIV    PROC    NEAR
  27.         JMP    START
  28.         ;
  29.         ; Stack frame structure.
  30.         ;
  31. STACKFRAME    STRUC    [BP]
  32. OLDBP        DW    ?    ; caller's BP
  33. RETADDR        DW    ?    ; return address
  34. DIVIDER        DW    ?    ; divider for Int 1Ah function 82h
  35. BUFFER        DD      ?       ; pointer to DMA buffer (65535 bytes long)
  36.         ENDS
  37.         ;
  38.         ; Local variables.
  39.         ;
  40. FIRSTBYTE    DD    0    ; linear address of first byte of buffer
  41. LASTBYTE    DD    0    ; linear address of last byte of buffer
  42. DACADDR        DW    0    ; base address of the DAC
  43. DMAADDR        DW    0    ; DMA starting address
  44. DMAPAGE        DB    0    ; DMA 64k page
  45. TICKCOUNT    DB    0    ; number of timer ticks since start of DMA
  46. INT08SAVE    DD    0    ; previous Int 8 handler
  47. ;
  48. ; Replacement timer tick interrupt handler.
  49. ;
  50. INT08HDLR:    PUSH    AX
  51.         INC    CS:TICKCOUNT        ; add to count of timer ticks
  52.         MOV    AL,20h
  53.         OUT    20h,AL
  54.         POP    AX
  55.         IRET
  56. ;
  57. ; Main subroutine.
  58. ;
  59. START:        PUSH    BP    ; preserve caller's BP
  60.         MOV    BP,SP    ; and address the parameters
  61.         PUSH    DS    ; save caller's DS
  62.         PUSH    CS    ; DS -> code segment
  63.         POP    DS
  64.         ;
  65.         ; Get DAC base address.
  66.         ;
  67.         MOV    AX,8100h
  68.         INT    1Ah
  69.         MOV    DACADDR,AX
  70.         ;
  71.         ; Compute starting and ending linear addresses of the buffer.
  72.         ;
  73.         MOV    AX,WORD PTR BUFFER
  74.         MOV    DX,WORD PTR BUFFER+2
  75.         MOV    CL,4
  76.         ROL    DX,CL
  77.         MOV    BX,DX
  78.         AND    DX,0Fh
  79.         AND    BX,0FFF0h
  80.         ADD    AX,BX
  81.         ADC    DX,0
  82.         MOV    WORD PTR FIRSTBYTE,AX
  83.         MOV    WORD PTR FIRSTBYTE+2,DX
  84.         ADD    AX,65534
  85.         ADC    DX,0
  86.         MOV    WORD PTR LASTBYTE,AX
  87.         MOV    WORD PTR LASTBYTE+2,DX
  88.         ;
  89.         ; If the low 16 bits of the address of the first byte is
  90.         ; less than 32k, there is 32k between the start of the
  91.         ; buffer and the 64k boundary.
  92.         ;
  93.         CMP    WORD PTR FIRSTBYTE,32768
  94.         JA    USELAST
  95.         MOV    AX,WORD PTR FIRSTBYTE
  96.         MOV    DH,BYTE PTR FIRSTBYTE+2
  97.         MOV    DMAADDR,AX
  98.         MOV    DMAPAGE,DL
  99.         JMP    SETDMA
  100.         ;
  101.         ; Otherwise, start DMA at the 64k boundary in the middle
  102.         ; of the buffer.
  103.         ;
  104. USELAST:    MOV    DMAADDR,0
  105.         MOV    AL,BYTE PTR LASTBYTE+2
  106.         MOV    DMAPAGE,DL
  107.         ;
  108.         ; Set up the DMA controller for the transfer.
  109.         ;
  110. SETDMA:        CLI
  111.         MOV    AL,5    ; disable DMA channel 1
  112.         OUT    0Ah,AL
  113.         JMP    $+2
  114.         MOV    AL,45h    ; select channel 1, write transfer to memory,
  115.         OUT    0Bh,AL    ;   autoinitialization disabled, address incre-
  116.         JMP    $+2    ;   ment, single mode
  117.         MOV    AL,DMAPAGE
  118.         OUT    83h,AL    ; set DMA channel 1 page register
  119.         JMP    $+2
  120.         MOV    AL,0FFh    ; clear byte pointer flip/flop
  121.         OUT    0Ch,AL
  122.         JMP    $+2
  123.         MOV    AL,-1
  124.         OUT    03h,AL    ; set DMA channel 1 count to maximum
  125.         JMP    $+2
  126.         OUT    03h,AL
  127.         JMP    $+2
  128.         MOV    AX,DMAADDR
  129.         OUT    02h,AL    ; set DMA channel 1 base address
  130.         JMP    $+2
  131.         MOV    AL,AH
  132.         OUT    02h,AL
  133.         ;
  134.         ; DMA controller is ready to go (when enabled).  Set up timer.
  135.         ;
  136.         MOV    AL,36h
  137.         OUT    43h,AL
  138.         JMP    $+2
  139.         MOV    AL,0    ; use maximum count (18.2 ticks/sec)
  140.         OUT    40h,AL
  141.         JMP    $+2
  142.         OUT    40h,AL
  143.         ;
  144.         ; Timer is ready.  Set up sound chip.
  145.         ;
  146.         MOV    DX,DACADDR
  147.         ADD    DX,2
  148.         MOV    AX,DIVIDER
  149.         OUT    DX,AL
  150.         JMP    $+2
  151.         INC    DX
  152.         MOV    AL,AH
  153.         OUT    DX,AL
  154.         ;
  155.         ; Sound chip is ready.  Hook Int 8.
  156.         ;
  157.         XOR    AX,AX
  158.         MOV    ES,AX
  159.         MOV    BX,20h
  160.         MOV    AX,ES:[BX]
  161.         MOV    WORD PTR INT08SAVE,AX
  162.         MOV    AX,ES:[BX+2]
  163.         MOV    WORD PTR INT08SAVE+2,AX
  164.         MOV    WORD PTR ES:[BX],OFFSET INT08HDLR
  165.         MOV    ES:[BX+2],CS
  166.         MOV    TICKCOUNT,0
  167.         STI
  168.         ;
  169.         ; Wait for two timer ticks.
  170.         ;
  171. WAIT1:        CMP    TICKCOUNT,2
  172.         JB    WAIT1
  173.         ;
  174.         ; Enable DMA channel 1 and start sound chip recording.
  175.         ;
  176.         CLI
  177.         MOV    AL,1
  178.         OUT    0Ah,AL
  179.         MOV    DX,DACADDR
  180.         IN    AL,DX
  181.         JMP    $+2
  182.         AND    AL,0E0h        ; recording with DMA, no EOP interrupt
  183.         OR    AL,6
  184.         OUT    DX,AL
  185.         MOV    TICKCOUNT,0
  186.         STI
  187.         ;
  188.         ; Wait for eight timer ticks.
  189.         ;
  190. WAIT2:        CMP    TICKCOUNT,8
  191.         JB    WAIT2
  192.         ;
  193.         ; Stop sound DMA.
  194.         ;
  195.         CLI
  196.         MOV    DX,DACADDR
  197.         IN    AL,DX
  198.         JMP    $+2
  199.         AND    AL,0FBh
  200.         OUT    DX,AL
  201.         ;
  202.         ; Unhook Int 8.  ES:BX -> Int 8 vector still, from above.
  203.         ;
  204.         MOV    AX,WORD PTR INT08SAVE
  205.         MOV    ES:[BX],AX
  206.         MOV    AX,WORD PTR INT08SAVE+2
  207.         MOV    ES:[BX+2],AX
  208.         ;
  209.         ; Get DMA channel 1 count.
  210.         ;
  211.         MOV    AL,0FFh    ; clear byte pointer flip/flop
  212.         OUT    0Ch,AL
  213.         JMP    $+2
  214.         IN    AL,03h
  215.         JMP    $+2
  216.         MOV    AH,AL
  217.         IN    AL,03h
  218.         XCHG    AL,AH
  219.         NOT    AX    ; return number of bytes transferred in AX
  220.         STI
  221.         POP    DS    ; restore caller's DS
  222.         POP    BP    ; restore caller's BP
  223.         RET    6    ; discard parameters
  224. TIME_DIV    ENDP
  225. CODE        ENDS
  226.         END
  227.